package com.tgu.home_action.controller;

import com.tgu.home_action.pojo.*;
import com.tgu.home_action.pojo.annotation.ApiJsonObject;
import com.tgu.home_action.pojo.annotation.ApiJsonProperty;
import com.tgu.home_action.pojo.exception.IMException;
import com.tgu.home_action.pojo.state.ResponseState;
import com.tgu.home_action.service.AdminService;
import io.jsonwebtoken.ExpiredJwtException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import java.io.IOException;
import java.text.ParseException;
import java.util.Map;

@Api(tags = "管理员端的用户管理")
@Validated
@RestController
@RequestMapping("/admin")
public class AdminController {
    @Autowired
    private Logger logger;

    @Autowired
    private AdminService adminService;

    /**
     * 登录
     *
     * @param admin ：登录信息
     * @return admin
     */
    @ApiOperation("登录")
    @PostMapping("/login")
    public ResponseData<Admin> login(@Validated(Admin.login.class) @RequestBody Admin admin) {
        return adminService.login(admin);
    }

    /**
     * 添加管理员
     *
     * @param adminBean：新增管理员账号密码
     * @param admin：当前登录的管理员
     * @return responseData
     */
    @ApiOperation("添加新的管理员(只有超管可操作)")
    @PreAuthorize("hasAnyRole('superAdmin')")
    @PostMapping("/add")
    public ResponseData<Admin> addAdmin(@Validated(Admin.login.class) @RequestBody Admin adminBean, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        try {
            return adminService.addAdmin(adminBean, admin);
        } catch (DuplicateKeyException e) {
            logger.warn(e.getMessage());
            return new ResponseData<>(ResponseState.ADMIN_IS_EXIST.getMessage(), ResponseState.ADMIN_IS_EXIST.getValue());
        }
    }

    /**
     * 添加地域管理员
     *
     * @param adminBean：新增管理员账号密码
     * @param admin：当前登录的管理员
     * @return responseData
     */
    @ApiOperation("添加新的区域管理员（必须提供地域信息，超管和管理员都可操作）")
    @PreAuthorize("hasAnyRole('superAdmin','admin')")
    @PostMapping("/districtAdmin/add")
    public ResponseData<Object> addDistrictAdmin(@Validated(Admin.login.class) @RequestBody Admin adminBean, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        try {
            return adminService.addDistrictAdmin(adminBean, admin);
        } catch (DuplicateKeyException e) {
            logger.warn(e.getMessage());
            return new ResponseData<>(ResponseState.ADMIN_IS_EXIST.getMessage(), ResponseState.ADMIN_IS_EXIST.getValue());
        }
    }

    /**
     * 获取管理员信息
     */
    @ApiOperation("获取本人信息")
    @PreAuthorize("hasAnyRole('superAdmin','admin','districtAdmin')")
    @GetMapping
    public ResponseData<Admin> getInfo(@ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        return adminService.getInfo(admin);
    }

    /**
     * 修改密码
     */
    @ApiOperation("修改密码")
    @PreAuthorize("hasAnyRole('superAdmin','admin','districtAdmin')") // 好像只有超管和管理员可以修改密码
    @PutMapping("/password")
    public ResponseData<Object> updatePassword(@ApiJsonObject(name = "UpdatePassword", value = {
            @ApiJsonProperty(key = "newPassword", description = "新密码"),
            @ApiJsonProperty(key = "oldPassword", description = "旧密码")
    }) @RequestBody Map<String, Object> param, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        String newPassword = (String) param.get("newPassword");
        String oldPassword = (String) param.get("oldPassword");
        return adminService.updatePassword(newPassword, oldPassword, admin);
    }

    /**
     * 删除管理员
     */
    @ApiOperation("删除管理员（普通管理员只能由超管删除）")
    @PreAuthorize("hasAnyRole('superAdmin','admin')")
    @DeleteMapping("/del")
    public ResponseData<Object> deleteAdmin(@RequestParam Integer id, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        return adminService.delete(id, admin);
    }

    /**
     * 修改管理员信息
     */
    @ApiOperation("修改下属管理员信息（普通管理员的信息只能由超管修改，信息包括密码和地域,id必须提供）")
    @PreAuthorize("hasAnyRole('superAdmin','admin')")
    @PutMapping("/update")
    public ResponseData<Object> updateAdminInfo(@Validated(Admin.update.class) @RequestBody Admin adminBean, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        try {
            return adminService.updateAdminInfo(adminBean, admin);
        } catch (DuplicateKeyException e) {
            logger.warn(e.getMessage());
            return new ResponseData<>(ResponseState.ADMIN_IS_EXIST.getMessage(), ResponseState.ADMIN_IS_EXIST.getValue());
        }
    }

    /**
     * 修改个人信息
     */
    @ApiOperation("修改本人地域信息（区域管理员不可操作）")
    @PreAuthorize("hasAnyRole('superAdmin','admin')")
    @PutMapping("/place")
    public ResponseData<Object> updatePlace(@RequestBody Admin adminBean, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        return adminService.updatePlace(adminBean, admin);
    }

    /**
     * 修改姓名/头像
     */
    @ApiOperation("修改本人的姓名/头像/性别")
    @PreAuthorize("hasAnyRole('superAdmin','admin','districtAdmin')")
    @PutMapping
    public ResponseData<Object> updateInfo(@RequestBody Admin adminBean, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        return adminService.updateInfo(adminBean, admin);
    }


    @ApiOperation("更新Token")
    @PostMapping("/refresh")
    public ResponseData<Object> refreshToken(@ApiJsonObject(name = "AdminRefreshToken",
            value = @ApiJsonProperty(key = "refreshToken", description = "refreshToken")) @RequestBody Map<String, Object> param) {
        try {
            return adminService.refreshToken((String) param.get("refreshToken"));
        } catch (ExpiredJwtException e) {
            logger.warn("token已过期");
            logger.error(e.getMessage());
            return new ResponseData<>(ResponseState.REFRESH_TOKEN_IS_EXPIRED.getMessage(), ResponseState.REFRESH_TOKEN_IS_EXPIRED.getValue());
        }
    }

    @ApiOperation("管理员上传图片")
    @PreAuthorize("hasAnyRole('superAdmin','admin','districtAdmin')")
    @PostMapping("/photo")
    public ResponseData<String> uploadPhoto(@RequestParam(required = true, name = "photo") MultipartFile photo, @ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        try {
            return adminService.uploadPhoto(photo, admin);
        } catch (IOException e) {
            logger.error("家属上传图片时获得文件流失败");
            logger.error(e.getMessage());
            return new ResponseData<>(ResponseState.NOT_CAN_GET_FILE_STREAM.getMessage(), ResponseState.NOT_CAN_GET_FILE_STREAM.getValue());
        }
    }

    @ApiOperation("查询管理员列表")
    @PreAuthorize("hasAnyRole('superAdmin','admin','districtAdmin')")
    @GetMapping("/all")
    public ResponseData<Page<Admin>> getAdmins(Admin admin) {
        return adminService.getAdmins(admin);
    }

    @ApiOperation("修改下属管理员的头像（普通管理员的信息只能由超管修改）")
    @PreAuthorize("hasAnyRole('superAdmin','admin')")
    @PutMapping("/avatar")
    public ResponseData<Object> updateAdminAvatar(@ApiJsonObject(name = "UpdateAdminAvatar", value = {
            @ApiJsonProperty(key = "id", description = "志愿者信息ID"),
            @ApiJsonProperty(key = "avatarUrl", description = "头像Url")
    }) @RequestBody Map<String, Object> param, @ApiIgnore @ModelAttribute("adminUser") Admin adminUser) {
        Integer id = Integer.valueOf((String) param.get("id"));
        String avatarUrl = (String) param.get("avatarUrl");
        return adminService.updateAdminAvatar(id, avatarUrl, adminUser);
    }

    @ApiOperation("通过ID查询管理员")
    @GetMapping("/id")
    public ResponseData<Admin> getAdminById(@RequestParam Integer id) {
        return adminService.getAdminById(id);
    }

    @ApiOperation("查询动态")
    @GetMapping("/dynamic")
    public ResponseData<Page<Dynamic>> getDynamic(Dynamic dynamic) {
        return adminService.getDynamic(dynamic);
    }

    @ApiOperation("查询团队指数")
    @GetMapping("/team")
    public ResponseData<Map<String, Team>> getTeam(Admin admin) {
        try {
            return adminService.getTeam(admin);
        } catch (ParseException e) {
            return new ResponseData<>(ResponseState.ERROR.getMessage(), ResponseState.ERROR.getValue());
        }
    }

    @ApiOperation("IM获取UserSig")
    @PreAuthorize("hasAnyRole('admin','districtAdmin','superAdmin')")
    @GetMapping("/im/userSig")
    public ResponseData<String> getUserSig(@ApiIgnore @ModelAttribute("adminUser") Admin admin) {
        try {
            return adminService.getUserSig(admin);
        } catch (IMException e) {
            return new ResponseData<>(e.getMessage(), ResponseState.IM_ERROR.getValue());
        }
    }
}
